package com.tbi.algorithm;

import java.util.List;

import com.tbi.algorithm.datacollector.EmptyAlgorithmStopDataCollector;
import com.tbi.algorithm.datacollector.EmptyDataCollector;
import com.tbi.algorithm.datacollector.IDataCollector;
import com.tbi.algorithm.datacollector.IStopperDataCollector;
import com.tbi.graphcolouring.datacollector.AlgorithmStopDataCollector;
import com.tbi.graphcolouring.datacollector.InitialPopulationCreationDataCollector;
import com.tbi.graphcolouring.datacollector.PostCrossoverDataCollector;
import com.tbi.graphcolouring.datacollector.PostEvaluationDataCollector;
import com.tbi.graphcolouring.datacollector.PostMutationDataCollector;
import com.tbi.graphcolouring.datacollector.PostSelectionDataCollector;

public class AlgorithmDataCollectorDecorator
		extends AbstractGenethicAlgorithm{
	
	private AbstractGenethicAlgorithm genethicAlgorithm;
	
	private IDataCollector initialPopulationCreationDataCollector
		= EmptyDataCollector.getInstance();
	private IDataCollector postEvaluationDataCollector
		= EmptyDataCollector.getInstance();
	private IDataCollector postSelectionDataCollector
		= EmptyDataCollector.getInstance();
	private IDataCollector postCrossoverDataCollector
		= EmptyDataCollector.getInstance();
	private IDataCollector postMutationDataCollector
		= EmptyDataCollector.getInstance();
	private IStopperDataCollector algorithmStopDataCollector
		= EmptyAlgorithmStopDataCollector.getInstance();
	
	public AlgorithmDataCollectorDecorator(
			AbstractGenethicAlgorithm genethicAlgorithm) {
		if(genethicAlgorithm == null) {
			throw new IllegalArgumentException();
		}
		this.genethicAlgorithm = genethicAlgorithm;
	}

	@Override
	protected void evaluate(List<Object> population) {
		genethicAlgorithm.evaluate(population);
		postEvaluationDataCollector.collectData(population);
	}

	@Override
	protected List<Object> createInitialPopulation(Object obj) {
		List<Object> initialPopulation = genethicAlgorithm.createInitialPopulation(obj);
		initialPopulationCreationDataCollector.collectData(initialPopulation);
		return initialPopulation;
	}

	@Override
	protected void selection(List<Object> population) {
		genethicAlgorithm.selection(population);
		postSelectionDataCollector.collectData(population);
	}

	@Override
	protected void crossover(List<Object> population) {
		genethicAlgorithm.crossover(population);
		postCrossoverDataCollector.collectData(population);
	}

	@Override
	protected void mutation(List<Object> population) {
		genethicAlgorithm.mutation(population);
		postMutationDataCollector.collectData(population);
	}

	@Override
	protected boolean stopCondition(List<Object> population, int generation) {
		boolean stopCondition = genethicAlgorithm.stopCondition(population, generation);
		algorithmStopDataCollector.collectData(population, generation);
		return stopCondition;
	}

	public void setPostEvaluationDataCollector(
			PostEvaluationDataCollector postEvaluationDataCollector) {
		this.postEvaluationDataCollector = postEvaluationDataCollector;
	}

	public void setInitialPopulationCreationDataCollector(
			InitialPopulationCreationDataCollector initialPopulationCreationDataCollector) {
		this.initialPopulationCreationDataCollector = initialPopulationCreationDataCollector;
	}

	public void setPostSelectionDataCollector(
			PostSelectionDataCollector postSelectionDataCollector) {
		this.postSelectionDataCollector = postSelectionDataCollector;
	}

	public void setPostMutationDataCollector(
			PostMutationDataCollector postMutationDataCollector) {
		this.postMutationDataCollector = postMutationDataCollector;
	}

	public void setAlgorithmStopDataCollector(
			AlgorithmStopDataCollector algorithmStopDataCollector) {
		this.algorithmStopDataCollector = algorithmStopDataCollector;
	}

	public void setPostCrossoverDataCollector(
			PostCrossoverDataCollector postCrossoverDataCollector) {
		this.postCrossoverDataCollector = postCrossoverDataCollector;
	}
}
